package com.springboot.blog.controller.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.springboot.blog.dto.LayPage;
import com.springboot.blog.dto.LayResponse;
import com.springboot.blog.entity.Article;
import com.springboot.blog.entity.ArticleTag;
import com.springboot.blog.entity.Category;
import com.springboot.blog.entity.Tag;
import com.springboot.blog.entity.vo.ArticleVO;
import com.springboot.blog.interfaces.ToolInterface;
import com.springboot.blog.service.IArticleService;
import com.springboot.blog.service.IArticleTagService;
import com.springboot.blog.service.ICategoryService;
import com.springboot.blog.service.ITagService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Controller
class AdminArticleController {
    @Autowired
    IArticleService articleService;
    @Autowired
    ITagService tagService;
    @Autowired
    IArticleTagService articleTagService;
    @Autowired
    ICategoryService categoryService;
    String PATH = "admin/article/";

    @RequiresPermissions("article:list")
    @GetMapping(value = {"/admin/article/index", "/admin/article"})
    public String index(Model model) {
        List<Category> list = categoryService.list(new QueryWrapper<Category>().lambda().orderByAsc(Category::getSorts));
        List<Category> list_sort = new ArrayList<>();
        unlimitedSort(list, list_sort, 0, 0);
        model.addAttribute("categories", list_sort);
        return PATH + "index";
    }

    @RequiresPermissions("article:list")
    @GetMapping(value = {"/admin/article/tree"})
    @ResponseBody
    public LayResponse tree(Integer page, Integer limit, Article article) {
        LambdaQueryWrapper<ArticleVO> wrapper = new QueryWrapper<ArticleVO>().lambda().orderByDesc(ArticleVO::getId);
        if (StringUtils.isNotEmpty(article.getTitle())) {
            wrapper.like(Article::getTitle, article.getTitle());
        }
        if (article.getTop() != null) {
            wrapper.eq(Article::getTop, article.getTop());
        }
        if (article.getRecommend() != null) {
            wrapper.eq(Article::getRecommend, article.getRecommend());
        }
        if (article.getHot() != null) {
            wrapper.eq(Article::getHot, article.getHot());
        }
        if (article.getCategoryId() != null && article.getCategoryId() != 0) {
            wrapper.eq(Article::getCategoryId, article.getCategoryId());
        }
        page = page == null ? 1 : page;
        limit = limit == null ? 10 : limit;
        LayPage<ArticleVO> pageArticle = new LayPage<>(page, limit);
        articleService.pageVO(pageArticle, wrapper);
        return pageArticle.getLayResponse();
    }

    @RequiresPermissions("article:delete")
    @PostMapping(value = {"/admin/article/delete"})
    @ResponseBody
    public LayResponse delete(String id) {
        boolean result = articleService.removeById(id);
        LayResponse layResponse = new LayResponse();
        if (result) {
            return layResponse.success();
        }
        return layResponse.error();
    }

    @RequiresPermissions("article:delete")
    @PostMapping(value = {"/admin/article/deleteAll"})
    @ResponseBody
    public LayResponse deleteAll(@RequestParam("ids[]") List<Integer> ids) {
        boolean result = articleService.removeByIds(ids);
        LayResponse layResponse = new LayResponse();
        if (result) {
            return layResponse.success();
        }
        return layResponse.error();
    }

    @RequiresPermissions("article:edit")
    @PostMapping(value = {"/admin/article/ajax"})
    @ResponseBody
    public LayResponse ajax(Article article) {
        boolean b = articleService.updateById(article);
        LayResponse layResponse = new LayResponse();
        if (b) {
            return layResponse.success();
        }
        return layResponse.error();
    }

    @RequiresPermissions("article:add")
    @GetMapping(value = {"/admin/article/add"})
    public String add(Model model) {
        List<Category> list = categoryService.list(new QueryWrapper<Category>().lambda().orderByAsc(Category::getSorts));
        List<Category> list_sort = new ArrayList<>();
        unlimitedSort(list, list_sort, 0, 0);
        model.addAttribute("categories", list_sort);
        return PATH + "add";
    }

    @RequiresPermissions("article:add")
    @PostMapping(value = {"/admin/article/add"})
    @ResponseBody
    public LayResponse add(@Validated(ToolInterface.insert.class) Article article, @RequestParam(name="tags[]",required = false) List<String> tags) {
        if (StringUtils.isEmpty(article.getIntroduction())) {
            String str = delHTMLTag(article.getContent());
            int strlen = Math.min(str.length(), 100);
            article.setIntroduction(str.substring(0, strlen));
        }
        articleService.save(article);
        if(tags!=null){
            for(String tagName:tags){
                LambdaQueryWrapper<Tag> wrapper = new QueryWrapper<Tag>().lambda().eq(Tag::getName,tagName);
                Tag tag = tagService.getOne(wrapper);
                if(tag==null){
                    tag=new Tag();
                    tag.setName(tagName);
                    tagService.save(tag);
                }
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(article.getId());
                articleTag.setTagId(tag.getId());
                articleTagService.save(articleTag);
            }
        }
        return new LayResponse().success();
    }

    public String delHTMLTag(String htmlStr) {
        String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
        String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
        String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
        Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); //过滤script标签
        Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); //过滤style标签
        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); //过滤html标签
        return htmlStr.trim().replace("　", ""); //返回文本字符串
    }

    private void unlimitedSort(List<Category> list, List<Category> list_sort, int pid, int level) {
        for (Category item : list) {
            if (item.getPid() == pid) {
                item.setTitle(StringUtils.repeat("　　", level) + "├" + item.getTitle());
                list_sort.add(item);
                unlimitedSort(list, list_sort, item.getId(), level + 1);
            }
        }
    }

    @RequiresPermissions("article:edit")
    @PostMapping(value = {"/admin/article/edit"})
    @ResponseBody
    public LayResponse edit(@Validated(ToolInterface.update.class) Article article, @RequestParam(name="tags[]",required = false) List<String> tags) {
        if (StringUtils.isEmpty(article.getIntroduction())) {
            String str = delHTMLTag(article.getContent());
            int strlen = Math.min(str.length(), 100);
            article.setIntroduction(str.substring(0, strlen));
        }
        articleService.updateById(article);
        if(tags!=null){
            for(String tagName:tags){
                LambdaQueryWrapper<Tag> wrapper = new QueryWrapper<Tag>().lambda().eq(Tag::getName,tagName);
                Tag tag = tagService.getOne(wrapper);
                if(tag==null){
                    tag=new Tag();
                    tag.setName(tagName);
                    tagService.save(tag);
                }
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(article.getId());
                articleTag.setTagId(tag.getId());
                articleTagService.save(articleTag);
            }
        }
        return new LayResponse().success();
    }
    @GetMapping(value = {"/admin/article/edit"})
    public String edit(@RequestParam Integer id,Model model) {
        Article data = articleService.getById(id);
        List<Category> list = categoryService.list(new QueryWrapper<Category>().lambda().orderByAsc(Category::getSorts));
        List<Category> list_sort = new ArrayList<>();
        unlimitedSort(list, list_sort, 0, 0);

        //查询标签
        List<ArticleTag> articleTagList = articleTagService.list(new QueryWrapper<ArticleTag>().lambda().eq(ArticleTag::getArticleId, data.getId()));
        List<Tag> tagList= Collections.emptyList();
        if (!articleTagList.isEmpty()) {
            List<Integer> tagIds = articleTagList.stream()
                    .map(ArticleTag::getTagId).collect(Collectors.toList());
            tagList = tagService.list(new QueryWrapper<Tag>().lambda().in(Tag::getId, tagIds));
        }
        model.addAttribute("categories", list_sort);
        model.addAttribute("data", data);
        model.addAttribute("tagList", tagList);
        return PATH + "edit";
    }
}
